#!/bin/sh

# jvm手动配置

# JAVA_OPTS相关的扩展参数(按实际情况扩展)
export JAVA_OPTS_EXT=""

# 设置jvm参数
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -server"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -Djava.awt.headless=true"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -Djavax.servlet.request.encoding=UTF-8"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -Dfile.encoding=UTF-8"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -Duser.language=zh_CN"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -Dsun.jnu.encoding=UTF-8"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -Djava.security.egd=file:/dev/./urandom"

export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -Xss256k"

export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -XX:+UnlockExperimentalVMOptions"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -XX:+UseCGroupMemoryLimitForHeap"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -XX:+UseContainerSupport"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -XX:InitialRAMPercentage=40.0"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -XX:MinRAMPercentage=20.0"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -XX:MaxRAMPercentage=80.0"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -XX:-UseAdaptiveSizePolicy"

export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -XX:ErrorFile=/app/hs_err_pid_%p.log"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -XX:+HeapDumpOnOutOfMemoryError"
export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -XX:HeapDumpPath=./"

#export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -XX:+PrintGCDetails" #用于打印输出详细的GC收集日志的信息.
#export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -XX:+PrintGCDateStamps"
#export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -XX:+PrintGCTimeStamps"

# #################start:手动自动适配内存######################

# 内存小于40%时，JVM就会增大堆直到-Xmx的最大限制；
# 空余堆内存大于70%时，JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx 相等以避免在每次GC 后调整堆的大小。
# 说明：如果-Xmx 不指定或者指定偏小，应用可能会导致java.lang.OutOfMemory错误，此错误来自JVM，不是Throwable的，无法用try...catch捕捉。

# JAVA_OPTS="$JAVA_OPTS -Xms3072m -Xmx6144m -Xss1024K -XX:MetaspaceSize=3072m -XX:MaxMetaspaceSize=4096m"

# 另：某位大神给出个比较合理的设置jvm参数。大多数机器都可以采用
#
#分配内存 堆配置推荐
#
#2G-Xmx1344M -Xms1344M -Xmn448M -XX:MaxMetaspaceSize=192M -XX:MetaspaceSize=192M
#
#3G-Xmx2048M -Xms2048M -Xmn768M -XX:MaxMetaspaceSize=256M -XX:MetaspaceSize=256M
#
#4G-Xmx2688M -Xms2688M -Xmn960M -XX:MaxMetaspaceSize=256M -XX:MetaspaceSize=256M
#
#5G-Xmx3392M -Xms3392M -Xmn1216M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M
#
#6G-Xmx4096M -Xms4096M -Xmn1536M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M
#
#7G-Xmx4736M -Xms4736M -Xmn1728M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M
#
#8G-Xmx5440M -Xms5440M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M
#
#完

# 获取docker限定使用的最大内存 使用 `docker run -m 1024m ...` 进行指定
limit_in_bytes=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes)

# If not default limit_in_bytes in cgroup  未指定docker最大内存时，获取到的数值为 9223372036854771712
if [ "$limit_in_bytes" -ne "9223372036854771712" ]
then
    # 单位转换为M
    limit_in_megabytes=$(expr $limit_in_bytes \/ 1048576)

    # 默认保留内存为1/4
    export RMS=$(expr $limit_in_megabytes \/ 4)
    # 为jvm保留内存(单位：M)
    # 最大保留内存2G => 超过2048 (2G内存) 使用2G空闲
    export RMS=$(($RMS>2048?2048:$RMS))
    # jvm最大内存(单位：M) JVM最大分配的堆内存由-Xmx指定，默认是物理内存的1/4
    # 默认使用最大内存为3/4
    export XMX=$(expr $limit_in_megabytes - $RMS)
    # jvm最小内存(单位：M) JVM初始分配的堆内存由-Xms指定，默认是物理内存的1/64
    # 默认最小内存为1/64，这里设置为1/4
#    export XMS=$(expr $limit_in_megabytes \/ 64)
#    export XMS=$(expr $limit_in_megabytes \/ 4)
    # 元空间大小(使用保留空间的1/2)
    export MMS=$(expr $RMS \/ 2)

    export JAVA_OPTS_EXT="$JAVA_OPTS_EXT -Xms"$XMX"m -Xmx"$XMX"m -XX:MetaspaceSize="$MMS"m -XX:MaxMetaspaceSize="$MMS"m"

fi

# #################end:手动自动适配内存######################

# 设置jvm参数到环境变量中
export JAVA_OPTS=" $JAVA_OPTS_EXT $JAVA_OPTS "

# 打印jvm参数
echo JAVA_OPTS_EXT=$JAVA_OPTS_EXT
echo JAVA_OPTS=$JAVA_OPTS

#springboot-jvm参数
export SPRING_BOOT_OPTS=""
export SPRING_BOOT_OPTS="$SPRING_BOOT_OPTS --spring.profiles.active=$MY_SPRING_PROFILES_ACTIVE"
export SPRING_BOOT_OPTS="$SPRING_BOOT_OPTS --server.port=8080"
# 可以通过命令行指定修改变量值
# docker run -e "SPRING_PROFILES_ACTIVE=dev" -e "SERVER_PORT=8080"

# 打印springboot启动参数
echo SPRING_BOOT_OPTS=$SPRING_BOOT_OPTS
# 打印命令行参数
echo COMMAND_LINE_ARGUMENT=$*

# 运行app.jar包
jarname=$JAR_NAME
if [ -z "$jarname" ] ;then
  # jar包名称为空
  jarname=app.jar
fi

# jar包文件路径
jarfile=/app/$jarname
# 判断文件是否存在
if [ -f "$jarfile" ] ;then
  # app.jar文件存在
  cd /app
  exec nohup java -jar $JAVA_OPTS $jarfile $SPRING_BOOT_OPTS $* >> /app/nohup.out &
  sleep 3  #等3秒后执行下一条
  exec tail -f /app/nohup.out
fi